package com.vipbbo.security.springboot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author bbo(zbw)
 * Description spring security提供了用户名密码登录、退出、会话管理等认证功能，只需要配置即可使用
 * @Date 2021/4/22
 */
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    // 定义用户信息服务（相当于查询信息）
/*    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("zhangsan").password("123").authorities("p1").build());
        inMemoryUserDetailsManager.createUser(User.withUsername("lisi").password("456").authorities("p2").build());
        return inMemoryUserDetailsManager;
    }*/

/*
    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance(); // 没有加密
    }
*/

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // 配置安全拦截机制（重要）
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /*http.csrf().disable()  避免403  解决方案一
        * 解决方案2
        *在login.jsp页面添加一个token，spring security会验证token，如果token合法则可以继续请求。
        修改login.jsp
        <form action="login" method="post">
        <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> ...
        </form>
        * */

//        super.configure(http);
        http.csrf().disable()
                .authorizeRequests()
//                .antMatchers("/r/r1").hasAuthority("p1") // 尽量使用资源、权限的方式拦截  这里是基于url的授权
//                .antMatchers("/r/r2").hasAuthority("p2")
                .antMatchers("/r/r**").authenticated() // 所有"/r/**" 的请求必须认证通过
                .anyRequest().permitAll() // 除了"/r/**" 其他请求都可以访问
                .and()
                .formLogin() // 允许表单登录
                .loginPage("/login-view") // 登录页面
                .loginProcessingUrl("/login")
                .successForwardUrl("/login-success") // 自定义登陆成功页面的地址
        .and()
                .sessionManagement() // 会话
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .logout()
                .logoutUrl("/logout")//自定义退出的url
                .logoutSuccessUrl("/login-view?logout");


    }
}
